package com.bizmda.bizsip.sample.sink.listener;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.bizmda.bizsip.common.BizException;
import com.bizmda.bizsip.common.BizResultEnum;
import com.bizmda.bizsip.common.BizUtils;
import com.bizmda.bizsip.sample.sink.longtcpnetty.NettyClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;

/**
 * RabbitMQ接收服务
 * @author shizhengye
 */
@Slf4j
@Service
public class LongTcpSinkQueueListener {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private NettyClient nettyClient;

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "queue.bizsip.long-tcp-netty-sink", durable = "true", autoDelete = "false"),
            exchange = @Exchange(value = "exchange.direct.bizsip.sink"),
            key = "key.bizsip.long-tcp-netty-sink"))
    public void onMessage(Message inMessage) {
        try {
            send(inMessage);
        } catch (BizException e) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.set("code",e.getCode());
            jsonObject.set("message",e.getMessage());
            jsonObject.set("extMessage",e.getExtMessage());
            Message outMessage = MessageBuilder.withBody(jsonObject.toString()
                    .getBytes(StandardCharsets.UTF_8))
                    .setCorrelationId(inMessage.getMessageProperties().getCorrelationId())
                    .build();
            rabbitTemplate.send("",
                    inMessage.getMessageProperties().getReplyTo(),
                    outMessage);
        }
        catch (Exception e) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.set("code",BizResultEnum.OTHER_ERROR);
            jsonObject.set("message",e.getMessage());
            Message outMessage = MessageBuilder.withBody(jsonObject.toString()
                            .getBytes(StandardCharsets.UTF_8))
                    .setCorrelationId(inMessage.getMessageProperties().getCorrelationId())
                    .build();
            rabbitTemplate.send("",
                    inMessage.getMessageProperties().getReplyTo(),
                    outMessage);
        }
    }

    private void send(Message inMessage) throws BizException {
        String correlationId = inMessage.getMessageProperties().getCorrelationId();
        String replyTo = inMessage.getMessageProperties().getReplyTo();
        byte[] bytes = inMessage.getBody();
        log.trace("correlationId,replayTo: {},{}",correlationId,replyTo);
        log.trace("message.getBody():\n{}",BizUtils.buildHexLog(bytes));

        String str = new String(bytes, StandardCharsets.UTF_8);
        JSONObject jsonObject = JSONUtil.parseObj(str);
        jsonObject.set("correlationId",correlationId);
        jsonObject.set("replyTo",replyTo);
        bytes = jsonObject.toString().getBytes(StandardCharsets.UTF_8);

        this.nettyClient.sendData(bytes);
    }
}
